
public class MySingleLinkedList implements SingleLinkedList {
	
	private int mySize = 0;
	private ListElement myFirst;
	private ListElement myLast;
	private int myMaxSize;
	
	public void setMaxSize(int maxSize) {
		myMaxSize = maxSize;
	}
	
	public boolean isEmpty() {
		return mySize == 0;
	}
	
	public int size() {
		return mySize;
	}

	private void incrementSize() {
        if (++mySize > myMaxSize) {
        	throw new RuntimeException("fhdgshghgfgh");
        }		
	}
	public void insertFirst(String value) {
		ListElement newHead = new ListElement(value);
		newHead.setNext(myFirst);
		myFirst = newHead;
        if (mySize == 0) {
            myLast = newHead;
        }
        incrementSize();
    }
	
	public void insertLast(String value) {
		if (mySize == 0) {
            insertFirst(value);
        } else {
            ListElement newLast = new ListElement(value);
		    myLast.setNext(newLast);
		    myLast = newLast;
            incrementSize();
        }
    }
	
	public void insert(String value, int position) {		
        if (position == 0) {
            insertFirst(value);
        } else if (mySize == position) {
            insertLast(value);            
        } else {
            checkPosition(position);
            ListElement iter = getByPosition(position - 1);
		    ListElement iter2 = iter.getNext();
		    ListElement inserting = new ListElement(value);
		    iter.setNext(inserting);
		    inserting.setNext(iter2);
            incrementSize();
        }
    }

    private ListElement getByPosition(int position) {
		checkPosition(position);
		int count = 0;
		ListElement iter = myFirst;
		while(count < position) {
            iter = iter.getNext();
			count++;
		}
        return iter;
	}
	
	private void checkPosition(int position) {
		if ((position < 0) || (position >= mySize)) {
			throw new IndexOutOfBoundsException();
		}
	}
	
	public String get(int position) {
		return getByPosition(position).getValue();
	}

    public void remove(int position) {
		checkPosition(position);
        if (position == 0) {
			ListElement head = myFirst;
			myFirst = myFirst.getNext();
            head.setNext(null);
        } else {
			ListElement before = getByPosition(position - 1);
			if (position == mySize - 1) {
				before.setNext(null);
				myLast = before;
			} else {
				ListElement forRemove = before.getNext();
				before.setNext(before.getNext().getNext());
                forRemove.setNext(null);
            }
		}
        mySize--;
    }
	
	public void clear() {
		myFirst = null;
        myLast = null;
        mySize = 0;
	}
    
    public void swap(int pos1, int pos2) {
		checkPosition(pos1);
		checkPosition(pos2);
		if (pos1 != pos2) {
			if (pos1 < pos2) {
                doSwap(pos1, pos2);
            } else {
                doSwap(pos2, pos1);
            }
		}
	}
	
	private void doSwap(int pos1, int pos2) {
		String string1 = get(pos1);
        String string2 = get(pos2);
        remove(pos1);
        remove(pos2 - 1);
        insert(string2, pos1);
        insert(string1, pos2);
    }

    public String toString() {
        if (myFirst != null) {
            StringBuffer sb = new StringBuffer(mySize);
            ListElement iter = myFirst;
            for (int i = 0; i < mySize; i++) {
                sb.append(" index=")
                  .append(i)
                  .append(" value=")
                  .append(iter.getValue())
                  .append("    ");
                iter = iter.getNext();
            }
            return sb.toString();
        } else {
            return "";
        }
    }
}